package org.itstack.demo.design;

import org.itstack.demo.design.event.EventManger;
import org.itstack.demo.design.event.listener.MQEventListener;
import org.itstack.demo.design.event.listener.MessageEventListener;

/**
 * @Author: fanYuLe
 * @CreateTime: 2023-12-28  13:40
 * @Description: 业务抽象类接⼝
 * 这种使⽤抽象类的⽅式定义实现⽅法，可以在⽅法中扩展需要的额外调⽤。并提供抽象
 * 类 abstract LotteryResult doDraw(String uId) ，让类的继承者实现。
 * 同时⽅法的定义使⽤的是 protected ，也就是保证将来外部的调⽤⽅不会调⽤到此⽅法，只有调
 * ⽤到 draw(String uId) ，才能让我们完成事件通知。
 * 此种⽅式的实现就是在抽象类中写好⼀个基本的⽅法，在⽅法中完成新增逻辑的同时，再增加抽象
 * 类的使⽤。⽽这个抽象类的定义会有继承者实现。
 * 另外在构造函数中提供了对事件的定
 * 义； eventManager.subscribe(EventManager.EventType.MQ, new
 * MQEventListener()) 。
 * 在使⽤的时候也是使⽤枚举的⽅式进⾏通知使⽤，传了什么类型
 * EventManager.EventType.MQ ，就会执⾏什么事件通知，按需添加。
 */
public abstract class LotteryService {
    private EventManger eventManger;
    public LotteryService(){
        eventManger = new EventManger(EventManger.EventType.MQ, EventManger.EventType.Message);
        eventManger.subscribe(EventManger.EventType.MQ,new MQEventListener());
        eventManger.subscribe(EventManger.EventType.Message,new MessageEventListener());
    }

    public LotteryResult draw(String uId){
        LotteryResult lotteryResult = doDraw(uId);
        //需要什么通知就调用什么方法
        eventManger.notify(EventManger.EventType.MQ,lotteryResult);
        eventManger.notify(EventManger.EventType.Message,lotteryResult);
        return lotteryResult;
    }

    protected abstract LotteryResult doDraw(String uId);
}
